package com.mdd.admin.service.common.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.mdd.admin.service.common.IIndexService;
import com.mdd.common.config.GlobalConfig;
import com.mdd.common.dto.OrderGroupDto;
import com.mdd.common.dto.VisitGroupDto;
import com.mdd.common.dto.result.OrderGroupResultDto;
import com.mdd.common.dto.result.VisitGroupResultDto;
import com.mdd.common.entity.order.Order;
import com.mdd.common.entity.user.User;
import com.mdd.common.enums.OrderPayStatusEnum;
import com.mdd.common.mapper.article.ArticleMapper;
import com.mdd.common.mapper.order.OrderMapper;
import com.mdd.common.mapper.user.UserMapper;
import com.mdd.common.mapper.visit.IndexVisitMapper;
import com.mdd.common.utils.*;
import org.apache.commons.collections.CollectionUtils;
import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * 主页服务实现类
 */
@Service
public class IndexServiceImpl implements IIndexService {

    @Resource
    ArticleMapper articleMapper;

    @Resource
    private OrderMapper orderMapper;

    @Resource
    private UserMapper userMapper;

    @Resource
    private IndexVisitMapper visitMapper;


    /**
     * 控制台数据
     *
     * @return Map<String, Object>
     * @author fzr
     */
    @Override
    public Map<String, Object> console() {
        Map<String, Object> console = new LinkedHashMap<>();

        // 版本信息
        Map<String, Object> version = new LinkedHashMap<>();
        version.put("name", ConfigUtil.get("website", "name", "LikeAdmin-Java"));
        version.put("version", GlobalConfig.version);
        version.put("website", "www.likeadmin.cn");
        version.put("based", "Vue3.x、ElementUI、MySQL");
        Map<String, String> channel = new LinkedHashMap<>();
        channel.put("gitee", "https://gitee.com/likeadmin/likeadmin_java");
        channel.put("website", "https://www.likeadmin.cn");
        version.put("channel", channel);
        console.put("version", version);

        // 今日数据
        Map<String, Object> today = new LinkedHashMap<>();
        today.put("time", "2022-08-11 15:08:29");
        today.put("todayVisits", 10);   // 访问量(人)
        today.put("totalVisits", 100);  // 总访问量
        today.put("todaySales", 30);    // 销售额(元)
        today.put("totalSales", 65);    // 总销售额
        today.put("todayOrder", 12);    // 订单量(笔)
        today.put("totalOrder", 255);   // 总订单量
        today.put("todayUsers", 120);   // 新增用户
        today.put("totalUsers", 360);   // 总访用户
        console.put("today", today);

        // 访客图表
        Map<String, Object> visitor = new LinkedHashMap<>();
        visitor.put("date", TimeUtil.daysAgoDate(15));
        visitor.put("list", Arrays.asList(12, 13, 11, 5, 8, 22, 14, 9, 456, 62, 78, 12, 18, 22, 46));
        console.put("visitor", visitor);

        return console;
    }

    /**
     * 公共配置
     *
     * @return Map<String, Object>
     * @author fzr
     */
    @Override
    public Map<String, Object> config() {
        Map<String, String> website = ConfigUtil.get("website");
        String copyright = ConfigUtil.get("website", "copyright", "");

        System.out.println(UrlUtil.toRelativeUrl("http://127.0.0.1:8082/uploads/image/20220426/8984bec1-57d6-4635-a110-fb4b26335879.png"));

        Map<String, Object> map = new LinkedHashMap<>();
        map.put("webName", website.getOrDefault("name", ""));
        map.put("webLogo", UrlUtil.toAbsoluteUrl(website.getOrDefault("logo", "")));
        map.put("webFavicon", UrlUtil.toAbsoluteUrl(website.getOrDefault("favicon", "")));
        map.put("webBackdrop", UrlUtil.toAbsoluteUrl(website.getOrDefault("backdrop", "")));
        map.put("ossDomain", UrlUtil.domain());
        map.put("copyright", ArrayUtil.stringToListAsMapStr(copyright));

        return map;
    }

    @Override
    public Map<String, Object> workbench() {
        Map<String, Object> workbench = new LinkedHashMap<>();
        // 版本信息
        Map<String, Object> version = new LinkedHashMap<>();
        version.put("name", ConfigUtil.get("website", "name", "上门预约"));
        version.put("version", GlobalConfig.version);
        workbench.put("version", version);
        //统计数据
        workbench.put("today", statisticsData());
        //常用功能
        workbench.put("menu", setMenu());
        //销售额趋势图（近15天）
        workbench.put("business", businessMap());
        // 用户访问量
        workbench.put("visitor", visitorMap());
        // 获取系统版本
        String isNewVersion = getSystemVersion();
        workbench.put("isNewVersion", isNewVersion);
        return workbench;
    }

    @NotNull
    private Map<String, Object> statisticsData() {
        // 今日销量
        LambdaQueryWrapper<Order> orderTodayWrapper = new LambdaQueryWrapper<>();
        List<Long> todayTime = TimeUtil.today();
        orderTodayWrapper.ge(Order::getPayTime, todayTime.get(0));
        orderTodayWrapper.le(Order::getPayTime, todayTime.get(1));
        orderTodayWrapper.eq(Order::getPayStatus, OrderPayStatusEnum.PAY.getStatus());
        List<Order> orderTodayList = orderMapper.selectList(orderTodayWrapper);
        Integer todaySalesCount = 0;
        BigDecimal todaySalesAmount = BigDecimal.ZERO;
        if (CollectionUtils.isNotEmpty(orderTodayList)) {
            for (Order order : orderTodayList) {
                todaySalesCount += order.getTotalNum();
                todaySalesAmount = todaySalesAmount.add(order.getTotalAmount());
            }
        }
        LambdaQueryWrapper<Order> orderWrapper = new LambdaQueryWrapper<>();
        orderWrapper.eq(Order::getPayStatus, OrderPayStatusEnum.PAY.getStatus());
        List<Order> orderList = orderMapper.selectList(orderWrapper);
        Integer totalSalesCount = 0;
        BigDecimal totalSalesAmount = BigDecimal.ZERO;
        if (CollectionUtils.isNotEmpty(orderList)) {
            for (Order order : orderList) {
                totalSalesCount += order.getTotalNum();
                totalSalesAmount = totalSalesAmount.add(order.getOrderAmount());
            }
        }
        // 今日访问
        LambdaQueryWrapper<User> todayUserMapper = new LambdaQueryWrapper<>();
        todayUserMapper.ge(User::getCreateTime, todayTime.get(0));
        todayUserMapper.le(User::getCreateTime, todayTime.get(1));
        int todayNewUser = userMapper.selectCount(todayUserMapper);
        int totalNewUser = userMapper.selectCount(new LambdaQueryWrapper<>());

        Map<String, Object> today = new LinkedHashMap<>();
        today.put("time", TimeUtil.timestampToDate(System.currentTimeMillis() / 1000));
        // 今日销量（笔）
        today.put("todaySalesCount", todaySalesCount);
        // 总的销量
        today.put("totalSalesCount", totalSalesCount);
        // 今日销售额(元)
        today.put("todaySalesAmount", todaySalesAmount);
        // 总的销售额
        today.put("totalSalesAmount", totalSalesAmount);
        // 今日新增会员
        today.put("todayNewUser", todayNewUser);
        // 总会员
        today.put("totalNewUser", totalNewUser);
        // 总访问量
        today.put("totalVisitor", 12);
        // 今日访问量
        today.put("todayVisitor", 12);
        return today;
    }

    private List<Map<String, String>> setMenu() {
        List<Map<String, String>> menuList = Lists.newArrayList();
        //服务列表
        Map<String, String> goodsMap = Maps.newHashMap();
        goodsMap.put("name", "服务列表");
        goodsMap.put("image", "");
        goodsMap.put("url", "/service/lists");
        goodsMap.put("method", "GET");
        menuList.add(goodsMap);
        //服务分类
        Map<String, String> goodsCategoryMap = Maps.newHashMap();
        goodsCategoryMap.put("name", "服务分类");
        goodsCategoryMap.put("image", "");
        goodsCategoryMap.put("url", "/service/category");
        goodsCategoryMap.put("method", "GET");
        menuList.add(goodsCategoryMap);
        //订单列表
        Map<String, String> orderMap = Maps.newHashMap();
        orderMap.put("name", "订单列表");
        orderMap.put("image", "");
        orderMap.put("url", "/order/lists");
        orderMap.put("method", "POST");
        menuList.add(orderMap);
        //师傅列表
        Map<String, String> staffMap = Maps.newHashMap();
        staffMap.put("name", "师傅列表");
        staffMap.put("image", "");
        staffMap.put("url", "/master_worker/index");
        staffMap.put("method", "POST");
        menuList.add(staffMap);
        //广告列表
        Map<String, String> adMap = Maps.newHashMap();
        adMap.put("name", "广告列表");
        adMap.put("image", "");
        adMap.put("url", "/decorate/index");
        adMap.put("method", "POST");
        menuList.add(adMap);
        //首页装修
        Map<String, String> decorateMap = Maps.newHashMap();
        decorateMap.put("name", "首页装修");
        decorateMap.put("image", "");
        decorateMap.put("url", "/decorate/index");
        decorateMap.put("method", "GET");
        menuList.add(decorateMap);
        //消息通知
        Map<String, String> noticeMap = Maps.newHashMap();
        noticeMap.put("name", "消息通知");
        noticeMap.put("image", "");
        noticeMap.put("url", "/setting/message/notice");
        noticeMap.put("method", "GET");
        menuList.add(decorateMap);
        //支付配置
        Map<String, String> payMap = Maps.newHashMap();
        payMap.put("name", "支付配置");
        payMap.put("image", "");
        payMap.put("url", "/setting/payment/payment_config");
        payMap.put("method", "GET");
        menuList.add(payMap);
        return menuList;
    }

    private Map<String, Object> visitorMap() {
        Map<String, Object> visitorMap = Maps.newHashMap();
        List<String> dateList = TimeUtil.daysAgoDate(15, true);
        visitorMap.put("date", dateList);
        Map<String, Object> dataMap = Maps.newHashMap();
        List<Long> conditionTime = TimeUtil.dayAgoToNow(15);
        VisitGroupDto dto = new VisitGroupDto();
        dto.setStartTime(conditionTime.get(0));
        dto.setEndTime(conditionTime.get(1));
        List<VisitGroupResultDto> resultList = visitMapper.groupVisit(dto);
        Map<String, Integer> visitCountMap = Maps.newHashMap();
        if (CollectionUtils.isNotEmpty(resultList)) {
            visitCountMap = resultList.stream().collect(Collectors.toMap(item -> item.getTime(), item -> item.getVisitCount(), (a, b) -> b));
        }
        List<Integer> dataList = new ArrayList<>();
        for (String date : dateList) {
            if (visitCountMap.containsKey(date)) {
                dataList.add(visitCountMap.get(date));
            } else {
                dataList.add(0);
            }
        }
        dataMap.put("data", dataList);
        visitorMap.put("list", dataMap);
        return visitorMap;
    }

    private Map<String, Object> businessMap() {
        Map<String, Object> businessMap = Maps.newHashMap();
        List<String> dateList = TimeUtil.daysAgoDate(15, true);
        businessMap.put("date", dateList);
        List<Map<String, Object>> list = Lists.newArrayList();
        Map<String, Object> nameMap = Maps.newHashMap();
        nameMap.put("name", "营业额");
        list.add(nameMap);
        List<Long> conditionTime = TimeUtil.dayAgoToNow(15);
        OrderGroupDto orderGroupDto = new OrderGroupDto();
        orderGroupDto.setPayStatus(OrderPayStatusEnum.PAY.getStatus());
        orderGroupDto.setStartTime(conditionTime.get(0));
        orderGroupDto.setEndTime(conditionTime.get(1));
        List<OrderGroupResultDto> orderList = orderMapper.groupSalesAmount(orderGroupDto);
        Map<String, BigDecimal> orderAmountMap = Maps.newHashMap();
        if (CollectionUtils.isNotEmpty(orderList)) {
            orderAmountMap = orderList.stream().collect(Collectors.toMap(item -> item.getOrderTime(), item -> item.getTotalAmount(), (a, b) -> b));
        }
        List<BigDecimal> dataList = new ArrayList<>();
        for (String date : dateList) {
            if (orderAmountMap.containsKey(date)) {
                dataList.add(orderAmountMap.get(date));
            } else {
                dataList.add(BigDecimal.ZERO);
            }
        }
        Map<String, Object> dataMap = Maps.newHashMap();
        dataMap.put("data", dataList);
        businessMap.put("list", dataMap);
        return businessMap;
    }

    private String getSystemVersion(){
        String result = "false";
        String version = "";
        //获取系统版本
        Map<String, String> system = ConfigUtil.get("system");
        String currentVersion = system.get("version");
        String versionRes = HttpUtil.sendGet("https://server.likeshop.cn/api/version/hasNew", "product_code=faf961f2d5af7a9d7ce30e5519ea2424&version=" + currentVersion);
        String pattern = "\"result\":(.*?),\"version\":\"(.*?)\"";
        Pattern r = Pattern.compile(pattern);
        Matcher m = r.matcher(versionRes);
        if (m.find()) {
            result = m.group(1);
            version = m.group(2);
        }
        if ("true".equals(result)){
            return "有新版本可用";
        }
        return "";
    }

}
